package com.ste.client;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import com.ste.client.service.CommandsHandler;
import com.ste.domain.Stock;
import com.ste.server.command.Trade.OrderType;

public class View extends JFrame {
	private static final long serialVersionUID = 1952404021071802942L;

	String columnNames[] = { "OrderID", "Stok", "Type", "Quantity", "Limit", "Status" };
	private Connector connector;

	public JTable ordersTable;
	private JPanel contentPane;
	private final JTextField quantityField;
	private final JTextField limitField;
	private final JComboBox<OrderType> operationTypeBox;
	private final JComboBox<LimitType> limitTypeBox;
	private final JComboBox<Stock> stockNameBox;
	private final JLabel statusLog;
	public JFrame loginFrame = new LoginFrame(View.this);

	private CommandsHandler commandsHandler = new CommandsHandler(this);

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					View frame = new View();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public View() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 628, 326);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		DefaultComboBoxModel<OrderType> orderTypes = new DefaultComboBoxModel<OrderType>(OrderType.values());
		operationTypeBox = new JComboBox<OrderType>(orderTypes);
		operationTypeBox.setBounds(161, 50, 100, 20);
		contentPane.add(operationTypeBox);

		quantityField = new JTextField();
		quantityField.setBounds(76, 50, 75, 20);
		contentPane.add(quantityField);
		quantityField.setColumns(10);

		DefaultComboBoxModel<LimitType> limitTypes = new DefaultComboBoxModel<LimitType>(LimitType.values());
		limitTypeBox = new JComboBox<LimitType>(limitTypes);
		limitTypeBox.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				limitField.setEditable(!LimitType.MARKET.equals(limitTypeBox.getSelectedItem()));
				limitField.setText("");
				contentPane.updateUI();
			}
		});

		limitTypeBox.setBounds(271, 50, 100, 20);
		contentPane.add(limitTypeBox);

		Label label = new Label("Operation Type");
		label.setBounds(161, 25, 100, 22);
		contentPane.add(label);

		Label label_1 = new Label("Quantity");
		label_1.setBounds(76, 25, 62, 22);
		contentPane.add(label_1);

		Label label_2 = new Label("Limit Type");
		label_2.setBounds(271, 25, 62, 22);
		contentPane.add(label_2);

		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBounds(10, 81, 592, 170);
		TableModel tableModel = new DefaultTableModel(columnNames, 0);
		ordersTable = new JTable(tableModel);
		tabbedPane.addTab("Orders", ordersTable);
		contentPane.add(tabbedPane);

		limitField = new JTextField();
		limitField.setBounds(377, 50, 91, 22);
		contentPane.add(limitField);

		JLabel lblLimit = new JLabel("Limit");
		lblLimit.setBounds(377, 25, 46, 14);
		contentPane.add(lblLimit);

		JLabel lblStock = new JLabel("Stock");
		lblStock.setBounds(10, 25, 46, 22);
		contentPane.add(lblStock);

		JButton btnSubmit = new JButton("Submit");
		btnSubmit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				statusLog.setText("");
				try {
					commandsHandler.createOrder((Stock)stockNameBox.getSelectedItem(), quantityField.getText(), (OrderType)operationTypeBox.getSelectedItem(), (LimitType)limitTypeBox.getSelectedItem() , limitField.getText());
				} catch (IllegalAccessException e1) {
					statusLog.setText(e1.getMessage());
				}
			}
		});
		btnSubmit.setBounds(495, 49, 89, 23);
		contentPane.add(btnSubmit);

		JButton btnLogin = new JButton("Login");
		btnLogin.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				loginFrame.setVisible(true);
			}
		});
		btnLogin.setBounds(495, 11, 89, 23);
		contentPane.add(btnLogin);
		
		statusLog = new JLabel("");
		statusLog.setForeground(Color.RED);
		statusLog.setBounds(10, 262, 592, 15);
		contentPane.add(statusLog);
		
		DefaultComboBoxModel<Stock> stockNames = new DefaultComboBoxModel<Stock>(Stock.values());
		stockNameBox = new JComboBox<Stock>(stockNames);
		stockNameBox.setBounds(10, 50, 56, 20);
		contentPane.add(stockNameBox);
	}

	public Connector getConnector() {
		return connector;
	}

	public void setConnector(Connector connector) {
		this.connector = connector;
	}

	public CommandsHandler getCommandsHandler() {
		return commandsHandler;
	}

	public void addOrder(String[] order) {
		DefaultTableModel model = (DefaultTableModel) ordersTable.getModel();
		model.addRow(order);
		contentPane.updateUI();
	}

	public void clearOrderFields() {
		limitField.setText("");
		quantityField.setText("");
		getStatusLog().setText("");
	}

	public void rejectOrder(String[] rejectedOrder) {
		operationTypeBox.setSelectedItem(OrderType.valueOf(rejectedOrder[2]));
		limitField.setText(rejectedOrder[4]);
		quantityField.setText(rejectedOrder[3]);
		stockNameBox.setSelectedItem(Stock.valueOf(rejectedOrder[1]));
		getStatusLog().setText("Format error");
	}

	public JLabel getStatusLog() {
		return statusLog;
	}

	public enum LimitType {
		LIMIT(2), MARKET(1);

		public final int value;

		private LimitType(int value) {
			this.value = value;
		}
	}
}
